package utils;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import domain.Lyric;

/**
 * Created by public1 on 2017/1/12.
 */

//解析歌词
public class LyriUtils {

    private ArrayList<Lyric> lyrics;

    public boolean isExitLyric() {
        return isExitLyric;
    }

    private boolean isExitLyric;//是否存在歌词

    public ArrayList<Lyric> getLyrics() {
        return lyrics;
    }

    /**读取歌词文件
     * @param file /mnt/scard/...
     */
    public ArrayList<Lyric> readLyricFile(File file) {

        if (file == null || !file.exists()){
            //无歌词文件
            lyrics = null;
            isExitLyric = false;
        } else {
            isExitLyric = true;
            //解析
            BufferedReader bufferedReader = null;
            try {
                //
                lyrics = new ArrayList<Lyric>();
                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file),getCharset(file)));

                String line = "";
                while ((line = bufferedReader.readLine()) != null){//读取一行

                    line = parseLyric(line);
                }
                bufferedReader.close();

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            //排序
            Collections.sort(lyrics, new Comparator<Lyric>() {
                @Override
                public int compare(Lyric lyric, Lyric t1) {
                    if (lyric.getTimePoint() < t1.getTimePoint()){
                        return -1;
                    } else if (lyric.getTimePoint() > t1.getTimePoint()){
                        return 1;
                    }
                    return 0;
                }
            });
            //高亮时间
            for (int i =0;i < lyrics.size();i++){
                Lyric lyric1 = lyrics.get(i);
                if (i+1 < lyrics.size()){
                    Lyric lyric2 = lyrics.get(i+1);
                    lyric1.setSleepTime(lyric2.getTimePoint() - lyric1.getTimePoint());
                }
            }
        }
        return null;
    }

    /**解析一句歌词 ： 【02:04.12】【03:04.12】【02:24.12】歌词歌词歌词
     * @param line
     * @return
     */
    private String parseLyric(String line) {

        //第一次出现【的位置
        int pos1 = line.indexOf("[");//如果没有返回-1
        int pos2 = line.indexOf("]");//如果没有返回-1

        if (pos1 == 0 && pos2 != -1){//有一句歌词
            //时间集合
            long[] times = new long[getCountTag(line)];

            String  strTime = line.substring(pos1+1,pos2);//02:04.12
            times[0] = strTimeToLongTime(strTime);

            //
            String content = line;
            int i = 1;
            while (pos1 == 0 && pos2 != -1) {
                content = content.substring(pos2+1); //【03:04.12】【02:24.12】歌词歌词歌词  -->  【02:24.12】歌词歌词歌词 --> 歌词歌词歌词
                pos1 = content.indexOf("[");//如果没有返回-1
                pos2 = content.indexOf("]");//如果没有返回-1

                if (pos2 != -1) {
                    strTime = content.substring(pos1 + 1,pos2);//03:04.12 --> 02:24.12
                    times[i] =  strTimeToLongTime(strTime);

                    if (times[i] == -1) {
                        return "";
                    }

                    i++;
                }

            }

            //把时间数组和歌词关联起来，加到集合

            for (int j = 0; j < times.length; j++){

                if (times[j] != 0) {//有时间戳
                    Lyric lyric = new Lyric();
                    lyric.setContent(content);
                    lyric.setTimePoint(times[j]);
                    lyrics.add(lyric);
                }
            }

            return content;
        }

        return null;
    }

    /**把02:04.12 转换成long类型
     * @param strTime
     * @return
     */
    private long strTimeToLongTime(String strTime) {
        long result = -1;
        try {

            //把02:04.12按照：切割02和04.12
            String[] s1 = strTime.split(":");
            //04.12按照：切割04和12
            String[] s2 = strTime.split("\\.");
            //分
            long minute = Long.parseLong(s1[0]);
            //秒
            long second = Long.parseLong(s2[0]);
            //毫秒
            long mil = Long.parseLong(s2[1]);

            result = (minute * 60 * 1000) + (second * 1000) + (mil * 10);
        } catch (Exception e) {
            e.printStackTrace();
            result = -1;
        }

        return result;
    }

    /**判断某一行有多少句歌词
     * @param line
     * @return
     */
    private int getCountTag(String line) {
        int result = -1;

        String[] left = line.split("\\[");
        String[] right = line.split("\\]");
        if (left.length == 0 && right.length == 0) {
            result = 1;
        } else if (left.length > right.length ) {
            result  = left.length;
        } else {
            result = right.length;
        }

        return result;
    }


    /**解决歌词乱码问题
     * @param file
     * @return
     */
    public static String getCharset(File file) {
        String charset = "GBK";
        byte[] first3Bytes = new byte[3];
        try {
            boolean checked = false;

            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream(file));
            bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "UTF-16LE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1]
                    == (byte) 0xFF) {
                charset = "UTF-16BE";
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1]
                    == (byte) 0xBB
                    && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF-8";
                checked = true;
            }
            bis.reset();
            if (!checked) {
                int loc = 0;
                while ((read = bis.read()) != -1) {
                    loc++;
                    if (read >= 0xF0)
                        break;
                    //单独出现BF以下的，也算是GBK
                    if (0x80 <= read && read <= 0xBF)
                        break;
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF)// 双字节 (0xC0 - 0xDF)
                            // (0x80 -
                            // 0xBF),也可能在GB编码内
                            continue;
                        else
                            break;
                        // 也有可能出错，但是几率较小
                    } else if (0xE0 <= read && read <= 0xEF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else
                                break;
                        } else
                            break;
                    }
                }
                System.out.println(loc + " " + Integer.toHexString(read));
            }
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return charset;
    }
}
